# -*- coding: utf-8 -*-

"""
时间和日期工具类
"""
import time
import datetime
import calendar


class TimeUtils(object):
    """
    时间和日期工具类
    """

    @staticmethod
    def get_current_time():
        """
        获取当前时间
        :return: 当前时间字符串
        """
        return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))

    @staticmethod
    def get_current_date():
        """
        获取当前日期
        :return: 当前日期字符串
        """
        return time.strftime('%Y-%m-%d', time.localtime(time.time()))

    @staticmethod
    def timestamp_to_time(timestamp):
        """
        时间戳转换为时间
        :param timestamp: 时间戳
        :return: 时间字符串
        """
        return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp))

    @staticmethod
    def time_to_timestamp(time_str):
        """
        时间转换为时间戳
        :param time_str: 时间字符串
        :return: 时间戳
        """
        return int(time.mktime(time.strptime(time_str, '%Y-%m-%d %H:%M:%S')))

    @staticmethod
    def date_to_timestamp(date_str):
        """
        日期转换为时间戳
        :param date_str: 日期字符串
        :return: 时间戳
        """
        return int(time.mktime(time.strptime(date_str, '%Y-%m-%d')))

    @staticmethod
    def timestamp_to_date(timestamp):
        """
        时间戳转换为日期
        :param timestamp: 时间戳
        :return: 日期字符串
        """
        return time.strftime('%Y-%m-%d', time.localtime(timestamp))

    @staticmethod
    def get_weekday(date_str):
        """
        获取日期是星期几
        :param date_str: 日期字符串
        :return: 星期几
        """
        return calendar.day_name[datetime.datetime.strptime(date_str, '%Y-%m-%d').weekday()]

    @staticmethod
    def get_month_days(year, month):
        """
        获取指定月份的天数
        :param year: 年份
        :param month: 月份
        :return: 天数
        """
        return calendar.monthrange(year, month)[1]

    @staticmethod
    def get_month_first_date(year, month):
        """
        获取指定月份的第一天日期
        :param year: 年份
        :param month: 月份
        :return: 第一天日期
        """
        return datetime.date(year, month, 1)

    @staticmethod
    def get_month_last_date(year, month):
        """
        获取指定月份的最后一天日期
        :param year: 年份
        :param month: 月份
        :return: 最后一天日期
        """
        return datetime.date(year, month, calendar.monthrange(year, month)[1])

    @staticmethod
    def get_last_month_first_date(year, month):
        """
        获取上个月份的第一天日期
        :param year: 年份
        :param month: 月份
        :return: 上个月份的第一天日期
        """
        last_month = month - 1 if month != 1 else 12
        last_year = year - 1 if month == 1 else year
        return datetime.date(last_year, last_month, 1)

    @staticmethod
    def get_last_month_last_date(year, month):
        """
        获取上个月份的最后一天日期
        :param year: 年份
        :param month: 月份
        :return: 上个月份的最后一天日期
        """
        last_month = month - 1 if month != 1 else 12
        last_year = year - 1 if month == 1 else year
        return datetime.date(last_year, last_month, calendar.monthrange(last_year, last_month)[1])

    @staticmethod
    def get_next_month_first_date(year, month):
        """
        获取下个月份的第一天日期
        :param year: 年份
        :param month: 月份
        :return: 下个月份的第一天日期
        """
        next_month = month + 1 if month != 12 else 1
        next_year = year + 1 if month == 12 else year
        return datetime.date(next_year, next_month, 1)

    @staticmethod
    def get_next_month_last_date(year, month):
        """
        获取下个月份的最后一天日期
        :param year: 年份
        :param month: 月份
        :return: 下个月份的最后一天日期
        """
        next_month = month + 1 if month != 12 else 1
        next_year = year + 1 if month == 12 else year
        return datetime.date(next_year, next_month, calendar.monthrange(next_year, next_month)[1])

    @staticmethod
    def get_last_week_date(date_str):
        """
        获取上周同一天的日期
        :param date_str: 日期字符串
        :return: 上周同一天的日期
        """
        date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
        last_week_date = date - datetime.timedelta(days=7)
        return last_week_date.strftime('%Y-%m-%d')

    @staticmethod
    def get_next_week_date(date_str):
        """
        获取下周同一天的日期
        :param date_str: 日期字符串
        :return: 下周同一天的日期
        """
        date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
        next_week_date = date + datetime.timedelta(days=7)
        return next_week_date.strftime('%Y-%m-%d')

    @staticmethod
    def get_last_month_date(date_str):
        """
        获取上个月同一天的日期
        :param date_str: 日期字符串
        :return: 上个月同一天的日期
        """
        date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
        last_month_date = date - datetime.timedelta(days=date.day)
        return last_month_date.strftime('%Y-%m-%d')

    @staticmethod
    def get_next_month_date(date_str):
        """
        获取下个月同一天的日期
        :param date_str: 日期字符串
        :return: 下个月同一天的日期
        """
        date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
        year = date.year if date.month != 12 else date.year + 1
        month = date.month + 1 if date.month != 12 else 1
        next_month_date = datetime.date(year, month, 1)
        return next_month_date.strftime('%Y-%m-%d')

    @staticmethod
    def get_day_diff(start_date_str, end_date_str):
        """
        获取两个日期之间相差的天数
        :param start_date_str: 起始日期字符串
        :param end_date_str: 结束日期字符串
        :return: 相差的天数
        """
        start_date = datetime.datetime.strptime(start_date_str, '%Y-%m-%d').date()
        end_date = datetime.datetime.strptime(end_date_str, '%Y-%m-%d').date()
        return (end_date - start_date).days

    @staticmethod
    def get_month_diff(start_date_str, end_date_str):
        """
        获取两个日期之间相差的月数
        :param start_date_str: 起始日期字符串
        :param end_date_str: 结束日期字符串
        :return: 相差的月数
        """
        start_date = datetime.datetime.strptime(start_date_str, '%Y-%m-%d').date()
        end_date = datetime.datetime.strptime(end_date_str, '%Y-%m-%d').date()
        return (end_date.year - start_date.year) * 12 + end_date.month - start_date.month

    @staticmethod
    def get_year_diff(start_date_str, end_date_str):
        """
        获取两个日期之间相差的年数
        :param start_date_str: 起始日期字符串
        :param end_date_str: 结束日期字符串
        :return: 相差的年数
        """
        start_date = datetime.datetime.strptime(start_date_str, '%Y-%m-%d').date()
        end_date = datetime.datetime.strptime(end_date_str, '%Y-%m-%d').date()
        return end_date.year - start_date.year

    @staticmethod
    def get_current_timestamp() -> int:
        """
        获取当前时间戳
        :return: 当前时间戳（单位：秒）
        """
        return int(time.time())

    @staticmethod
    def get_current_millisecond() -> int:
        """
        获取当前时间戳
        :return: 当前时间戳（单位：毫秒）
        """
        return int(time.time() * 1000)

    @staticmethod
    def timestamp_to_datetime(timestamp: int) -> datetime.datetime:
        """
        将时间戳转换为datetime对象
        :param timestamp: 时间戳（单位：秒）
        :return: datetime对象
        """
        return datetime.datetime.fromtimestamp(timestamp)

    @staticmethod
    def millisecond_to_datetime(millisecond: int) -> datetime.datetime:
        """
        将时间戳转换为datetime对象
        :param millisecond: 时间戳（单位：毫秒）
        :return: datetime对象
        """
        return datetime.datetime.fromtimestamp(millisecond / 1000)

    @staticmethod
    def datetime_to_timestamp(dt: datetime.datetime) -> int:
        """
        将datetime对象转换为时间戳
        :param dt: datetime对象
        :return: 时间戳（单位：秒）
        """
        return int(dt.timestamp())

    @staticmethod
    def datetime_to_millisecond(dt: datetime.datetime) -> int:
        """
        将datetime对象转换为时间戳
        :param dt: datetime对象
        :return: 时间戳（单位：毫秒）
        """
        return int(dt.timestamp() * 1000)

    @staticmethod
    def timestamp_to_string(timestamp: int, format_str: str = '%Y-%m-%d %H:%M:%S') -> str:
        """
        将时间戳转换为字符串
        :param timestamp: 时间戳（单位：秒）
        :param format_str: 时间格式化字符串
        :return: 格式化后的时间字符串
        """
        return datetime.datetime.fromtimestamp(timestamp).strftime(format_str)

    @staticmethod
    def millisecond_to_string(millisecond: int, format_str: str = '%Y-%m-%d %H:%M:%S') -> str:
        """
        将时间戳转换为字符串
        :param millisecond: 时间戳（单位：毫秒）
        :param format_str: 时间格式化字符串
        :return: 格式化后的时间字符串
        """
        return datetime.datetime.fromtimestamp(millisecond / 1000).strftime(format_str)

    @staticmethod
    def string_to_datetime(s: str, format_str: str = '%Y-%m-%d %H:%M:%S') -> datetime.datetime:
        """
        将字符串转换为datetime对象
        :param s: 时间字符串
        :param format_str: 时间格式化字符串
        :return: datetime对象
        """
        return datetime.datetime.strptime(s, format_str)

    @staticmethod
    def string_to_timestamp(s: str, format_str: str = '%Y-%m-%d %H:%M:%S') -> int:
        """
        将字符串转换为时间戳
        :param s: 时间字符串
        :param format_str: 时间格式化字符串
        :return: 时间戳（单位：秒）
        """
        return int(time.mktime(time.strptime(s, format_str)))

    @staticmethod
    def string_to_millisecond(s: str, format_str: str = '%Y-%m-%d %H:%M:%S') -> int:
        """
        将字符串转换为时间戳
        :param s: 时间字符串
        :param format_str: 时间格式化字符串
        :return: 时间戳（单位：毫秒）
        """
        return int(time.mktime(time.strptime(s, format_str)) * 1000)

    @staticmethod
    def datetime_to_string(dt: datetime.datetime, format_str: str = '%Y-%m-%d %H:%M:%S') -> str:
        """
        将datetime对象转换为字符串
        :param dt: datetime对象
        :param format_str: 时间格式化字符串
        :return: 格式化后的时间字符串
        """
        return dt.strftime(format_str)

    @staticmethod
    def get_current_datetime() -> datetime.datetime:
        """
        获取当前时间（datetime对象）
        :return: 当前时间（datetime对象）
        """
        return datetime.datetime.now()

    @staticmethod
    def get_current_datetime_string(format_str: str = '%Y-%m-%d %H:%M:%S') -> str:
        """
        获取当前时间字符串
        :param format_str: 时间格式化字符串
        :return: 格式化后的时间字符串
        """
        return datetime.datetime.now().strftime(format_str)

    @staticmethod
    def get_date_from_string(s: str, format_str: str = '%Y-%m-%d') -> datetime.date:
        """
        将字符串转换为date对象
        :param s: 日期字符串
        :param format_str: 日期格式化字符串
        :return: date对象
        """
        return datetime.datetime.strptime(s, format_str).date()

    @staticmethod
    def get_string_from_date(d: datetime.date, format_str: str = '%Y-%m-%d') -> str:
        """
        将date对象转换为字符串
        :param d: date对象
        :param format_str: 日期格式化字符串
        :return: 格式化后的日期字符串
        """
        return d.strftime(format_str)

    @staticmethod
    def get_datetime_from_string(s: str, format_str: str = '%Y-%m-%d %H:%M:%S') -> datetime.datetime:
        """
        将字符串转换为datetime对象
        :param s: 时间字符串
        :param format_str: 时间格式化字符串
        :return: datetime对象
        """
        return datetime.datetime.strptime(s, format_str)

    @staticmethod
    def get_string_from_datetime(dt: datetime.datetime, format_str: str = '%Y-%m-%d %H:%M:%S') -> str:
        """
        将datetime对象转换为字符串
        :param dt: datetime对象
        :param format_str: 时间格式化字符串
        :return: 格式化后的时间字符串
        """
        return dt.strftime(format_str)

    @staticmethod
    def get_days_between(start_date: datetime.date, end_date: datetime.date) -> int:
        """
        计算两个日期之间的天数
        :param start_date: 起始日期（date对象）
        :param end_date: 结束日期（date对象）
        :return: 两个日期之间的天数
        """
        return (end_date - start_date).days

    @staticmethod
    def get_weekday_from_date(d: datetime.date) -> int:
        """
        获取日期的星期几
        :param d: date对象
        :return: 星期几（0代表星期一，1代表星期二，以此类推）
        """
        return d.weekday()

    @staticmethod
    def get_weekday_from_datetime(dt: datetime.datetime) -> int:
        """
        获取datetime对象所在日期的星期几
        :param dt: datetime对象
        :return: 星期几（0代表星期一，1代表星期二，以此类推）
        """
        return dt.weekday()

    @staticmethod
    def get_weekday_name_from_date(d: datetime.date) -> str:
        """
        获取日期的星期几的名称
        :param d: date对象
        :return: 星期几的名称（例如：'星期一'）
        """
        weekday_names = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
        return weekday_names[d.weekday()]

    @staticmethod
    def get_weekday_name_from_datetime(dt: datetime.datetime) -> str:
        """
        获取datetime对象所在日期的星期几的名称
        :param dt: datetime对象
        :return: 星期几的名称（例如：'星期一'）
        """
        weekday_names = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
        return weekday_names[dt.weekday()]

    @staticmethod
    def get_month_name_from_date(d: datetime.date) -> str:
        """
        获取日期所在月份的名称
        :param d: date对象
        :return: 月份的名称（例如：'一月'）
        """
        month_names = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
        return month_names[d.month - 1]


if __name__ == '__main__':
    print("Python")
    print("20241105122598"[:-2])
    print("20241105122598"[0:13])
    print("202411051225"[0:13])
    print(TimeUtils.get_datetime_from_string("20241105122598"[:-2], "%Y%m%d%H%M%S"))
    print(TimeUtils.get_current_datetime().hour)
